import io
from typing import List

from win2xcur.cursor import CursorFrame
from wand.image import Image

import numpy
import PIL.Image as pil 

def gcd(a, b):
    return a if b==0 else gcd(b, a%b)


def to_gif(frames: List[CursorFrame]) -> bytes:
    imgs = []
    min_speed = 0
    for frame in frames:
        min_speed = gcd(round(frame.delay*1000), min_speed) if round(frame.delay*1000) != 0 else 0
    if min_speed == 0:
        raise ZeroDivisionError("最小delay为0，无法成功解析")
    for frame in frames:
        cnt = round(frame.delay*1000/min_speed)
        for i in range(cnt):
            for cursor in frame:
                with Image(cursor.image) as sin:
                    sin.format = "png"
                    img = pil.open(io.BytesIO(sin.make_blob()))
                    imgs.append(img)
    return (imgs, min_speed)


def to_pngs(frames: List[CursorFrame]) -> list:
    cnt = 0
    imgs = []
    for frame in frames:
        for cursor in frame:
            with Image(cursor.image) as sin:
                sin.format = "png"
                cnt+=1
                img_buffer=numpy.asarray(bytearray(sin.make_blob()), dtype=numpy.uint8)
                imgs.append(img_buffer)
    return imgs

def to_png(frames: List[CursorFrame]) -> list:
    cnt = 0
    imgs = []
    for frame in frames:
        for cursor in frame:
            with Image(cursor.image) as sin:
                sin.format = "png"
                cnt+=1
                img = pil.open(io.BytesIO(sin.make_blob()))
                imgs.append(img.convert("RGBA"))
    ROW = len(imgs)
    step = ROW / 24 if ROW > 24 else 1
    UNIT_WIDTH_SIZE, UNIT_HEIGHT_SIZE = imgs[0].size
    target = pil.new('RGBA', (UNIT_WIDTH_SIZE, UNIT_HEIGHT_SIZE * (ROW if ROW < 24 else 24))) 
    row = 0
    cnt = 0
    while row < ROW:
        target.paste(imgs[round(row)], (0, UNIT_HEIGHT_SIZE*cnt))
        row = row+step
        cnt += 1
    return target